package org.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.json.simple.JSONValue;
import org.model.*;
import org.model.Thread;
import org.service.ForumService;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * Created by tedzy on 2015/5/14.
 * forum Action
 */
public class ForumAction extends ActionSupport {
    private ForumService forumService;
    private int threadid = 0;
    private int id=0;
    private String title;
    private String postTime;
    private List<Floor> floors;
    private Map<Integer, List<Floor>> inFloors;
    private List<Thread> threads;
    private Map<Integer, Integer> repliesCount;
    private String content;
    private String jsonResult;
    private DateFormat sdf;

    /**
     * 建立新讨论串
     * URL: /forum/newthread.json
     * 方法: POST
     * 备注: 需要在已经登录的状态
     * 参数: title 讨论串标题, content 一楼的内容
     * @return result: error 出错, success 成功
     *         info: result=error时返回，错误信息
     *         threadid: result=success时返回，新帖的贴号
     */
    public String newThread() {
        Map<String, Object> json = new LinkedHashMap<>();
        boolean check = true;
        User user = isLogin();
        if(user == null || user.getId() == 0){
            json.put("result", "error");
            json.put("info", "请先登录。");
            check = false;
        }
        if(title == null || title.equals("")){
            json.put("result", "error");
            json.put("info", "标题不能为空。");
            check = false;
        }
        if(content == null || content.equals("")){
            json.put("result", "error");
            json.put("info", "内容不能为空。");
            check = false;
        }
        if(check){
            int threadid = forumService.newThread(title);
            int floorid = forumService.newFloor(threadid, user.getId(), content);
            if(!forumService.addFloor(threadid, floorid)){
                json.put("result", "error");
                json.put("info", "数据库增加内容失败。");
            }else{
                json.put("result", "success");
                json.put("threadid", threadid);
            }
        }

        jsonResult = JSONValue.toJSONString(json);
        return SUCCESS;
    }

    /**
     * 回复讨论串。
     * URL: /forum/reply.json 方法POST
     * 要求: 登录用户
     * 参数: threadid: 贴号, content 内容
     * @return result与上面函数result相同。
     */
    public String reply(){
        Map<String, Object> json = new LinkedHashMap<>();
        boolean check = true;
        User user = isLogin();
        if(user == null || user.getId() == 0){
            json.put("result", "error");
            json.put("info", "请先登录。");
            check = false;
        }
        if(threadid <= 0 ){
            json.put("result", "error");
            json.put("info", "主题ID不存在。");
            check = false;
        }
        if(content == null || content.equals("")){
            json.put("result", "error");
            json.put("info", "内容不能为空。");
            check = false;
        }
        if(check){
            int newFloorId = forumService.newFloor(threadid, user.getId(), content);
            if(!forumService.addFloor(threadid, newFloorId)){
                json.put("result", "error");
                json.put("info", "主题贴不存在。");
            }else{
                json.put("result", "success");
            }
        }
        jsonResult = JSONValue.toJSONString(json);
        return SUCCESS;
    }

    /**
     * 回复楼中楼。
     * URL: /forum/replyinfloor.json 方法POST
     * 要求: 登录用户
     * 参数: threadid: 父楼层号, content 内容
     * @return result与上面函数result相同。
     */
    public String replyInFloor(){
        Map<String, Object> json = new LinkedHashMap<>();
        boolean check = true;
        User user = isLogin();
        if(user == null || user.getId() == 0){
            json.put("result", "error");
            json.put("info", "请先登录。");
            check = false;
        }
        if(threadid <= 0 ){
            json.put("result", "error");
            json.put("info", "主题ID不存在。");
            check = false;
        }
        if(content == null || content.equals("")){
            json.put("result", "error");
            json.put("info", "内容不能为空。");
            check = false;
        }
        if(check){
            int newFloorId = forumService.newInFloor(threadid, user.getId(), content);
            if(!forumService.addInFloor(threadid, newFloorId)){
                json.put("result", "error");
                json.put("info", "父楼层不存在。");
            }else{
                json.put("result", "success");
            }
        }
        jsonResult = JSONValue.toJSONString(json);
        return SUCCESS;
    }

    /**
     * 阅读帖子。
     * URL: /thread/{ID}
     * 原始: /forum/readthread.json?threadid={ID} 方法:GET
     * 参数: threadid 帖子id，通过URL传入。
     * @return jsp 目标页面
     */
    public String readThread(){
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        if(threadid <= 0){
            jsonResult = "帖子ID不存在。";
            content = "/threads";
            return INPUT;
        }
        org.model.Thread thread = forumService.readThread(threadid);
        if(thread == null){
            jsonResult = "没有此帖子。";
            content = "/threads";
            return ERROR;
        }
        title = thread.getTitle();
        postTime = thread.getPostTime().toString();
        inFloors = new LinkedHashMap<>();
        floors = forumService.readFloors(thread.getFloorid());
        floors.stream().filter(fl -> fl.getInfloorId() != null && !fl.getInfloorId().equals(""))
                .forEach(fl -> inFloors.put(fl.getId(), forumService.readFloors(fl.getInfloorId())));

        return SUCCESS;
    }

    /**
     * 获得帖子列表
     * URL: /threads
     * 原始URL: /forum/threads.json 方法: GET
     * 传入参数: 无
     * @return jsp 直接生成目标页面
     */
    public String threads(){
        threads = forumService.getThreads();
        repliesCount = new LinkedHashMap<>();
        threads.stream().filter(t -> t.getFloorid() != null && !t.getFloorid().equals(""))
                .forEach(t -> repliesCount.put(t.getId(), (t.getFloorid().split(",")).length));
        return SUCCESS;
    }

    public String incZan(){
        Map<String, Object> json = new LinkedHashMap<>();
        int res = forumService.incZan(id);
        json.put("result", res);
        jsonResult = JSONValue.toJSONString(json);
        return SUCCESS;
    }


    private User isLogin(){
        Map<String, Object> session = ActionContext.getContext().getSession();
        Object login_status = session.get("login_status");
        if(login_status != null && (boolean) login_status){
            return (User) session.get("login_user");
        }else{
            return null;
        }
    }

    public ForumService getForumService() {
        return forumService;
    }

    public void setForumService(ForumService forumService) {
        this.forumService = forumService;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getJsonResult() {
        return jsonResult;
    }

    public void setJsonResult(String jsonResult) {
        this.jsonResult = jsonResult;
    }

    public int getThreadid() {
        return threadid;
    }

    public void setThreadid(int threadid) {
        this.threadid = threadid;
    }

    public String getPostTime() {
        return postTime;
    }

    public void setPostTime(String postTime) {
        this.postTime = postTime;
    }

    public List<Floor> getFloors() {
        return floors;
    }

    public void setFloors(List<Floor> floors) {
        this.floors = floors;
    }

    public Map<Integer, List<Floor>> getInFloors() {
        return inFloors;
    }

    public void setInFloors(Map<Integer, List<Floor>> inFloors) {
        this.inFloors = inFloors;
    }

    public List<Thread> getThreads() {
        return threads;
    }

    public void setThreads(List<Thread> threads) {
        this.threads = threads;
    }

    public Map<Integer, Integer> getRepliesCount() {
        return repliesCount;
    }

    public void setRepliesCount(Map<Integer, Integer> repliesCount) {
        this.repliesCount = repliesCount;
    }

    public DateFormat getSdf() {
        return sdf;
    }

    public void setSdf(DateFormat sdf) {
        this.sdf = sdf;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
